package com.csx.governance.traffic.route.model;

import com.csx.governance.traffic.condition.ParsedExpression;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.Locale;

/**
 * 条件表达式
 * @author cuisongxu
 * @date 2023/2/24 16:32
 */
public class ConditionExpression extends ArrayList<ConditionExpression.Expression> {

    private ParsedExpression parsedExpression;

    @NoArgsConstructor
    @Data
    public static class Expression {
        /**
         * 表达式类型
         */
        private Type type;

        /**
         * 参数键,Type为 {@link Type#EXP} 时才生效
         */
        private String paramKey;

        /**
         * 操作符,Type为 {@link Type#EXP} 时才生效
         */
        private String operation;

        /**
         * 参数值,Type为 {@link Type#EXP} 时才生效
         */
        private String paramValue;

        /**
         * 逻辑运算符,Type为 {@link Type#LOGIC} 时才生效
         */
        private String logic;

        /**
         * 构造Expression唯一接口
         * @param type 表达式类型
         * @param params 参数列表 顺序为paramKey, operation, paramValue
         * @return Expression Object
         */
        public static Expression buildExpression(Type type, String... params) {
            if(Type.LOGIC.equals(type) && params.length > 0) {
                return new Expression(params[0]);
            }else if(Type.EXP.equals(type)) {
                return new Expression(params[0], params[1], params[2]);
            }else {
                throw new IllegalArgumentException("Illegal Expression Params");
            }
        }

        private Expression(String logic) {
            this.logic = logic;
            this.type = Type.LOGIC;
            this.paramKey = null;
            this.paramValue = null;
            this.operation = null;
        }

        private Expression(String paramKey, String operation, String paramValue) {
            this.logic = null;
            this.type = Type.EXP;
            this.paramKey = paramKey;
            this.paramValue = paramValue;
            this.operation = operation;
        }

        public void setType(String type) {
            this.type = Type.valueOf(type.toUpperCase(Locale.ROOT));
        }

        public String getType() {
            return type.name().toLowerCase(Locale.ROOT);
        }

        public String[] getParams() {
            if(Type.LOGIC.equals(type)) {
                return new String[]{this.logic};
            }else {
                return new String[]{this.paramKey, this.operation, this.paramValue};
            }
        }
    }

    public ParsedExpression getParsedExpression() {
        return parsedExpression;
    }

    public void setParsedExpression(ParsedExpression parsedExpression) {
        this.parsedExpression = parsedExpression;
    }

    /**
     * 表达式类型
     */
    enum Type {

        /**
         * 逻辑表达式
         */
        LOGIC,

        /**
         * 比较表达式
         */
        EXP;
    }
}
